/**
 * @description 表单服务
 * @author Rid King
 * @since 2018-07-06
 */

import objecter from '../../../objecter/2.0.0/js/objecter'
import urler from '../../../urler/2.0.0/js/urler'
import Service from '../../../service/2.0.0/js/service'

/**
 * @class Form服务类
*/
class FormService extends Service {
  /**
   * @desc 发送请求
   * @param options <Object> 配置
   * @return <Promise>
   * */
  _send (options) {
    let me = this
    // 复制配置
    options = objecter.clone(options)
    // 是否超时
    let isTimeout = false
    // 请求参数
    let params =  ''
    // 请求状态
    let state = 0

    // 如果是GET请求，拼接url
    if (/get/i.test(options.method)) {
      if (options.data) {
        options.url += '?' + urler.stringify(options.data)
      }
      options.data = ''
    } else {
      // 数据为数组格式时，请求设置为json
      if (Array.isArray(options.data)) {
        options.headers['Content-Type'] = 'application/json;charset=UTF-8'
      }
      else if (objecter.isObject(options.data)) {
        // 检查数据中是否含有对象
        let hasObject = false
        for (let key in options.data) {
          if (objecter.isObject(options.data[key])) {
            hasObject = true
            break
          }
        }
        // 数据中含有对象
        if (hasObject) {
          options.headers['Content-Type'] = 'application/json;charset=UTF-8'
        }
      }

      // 参数设置
      if (options.data) {
        if (/json/.test(options.headers['Content-Type'])) {
          params = JSON.stringify(options.data)
        } else {
          params = urler.stringify(options.data)
        }
      }
      options.body = params
    }

    return new Promise((resolve, reject) => {
      // 首先创建一个用来发送数据的iframe
      const iframe = document.createElement('iframe')
      iframe.name = 'iframeForm'
      iframe.style.display = 'none'
      document.body.appendChild(iframe)
      // 注册iframe的load事件处理程序,如果你需要在响应返回时执行一些操作的话
      iframe.addEventListener('load', function () {
        // 已超时
        if (isTimeout) {
          return false
        }

        state = 4
        if (status >= 200 && status < 300) {
          resolve(me.parse(xhr.responseText, options.dataType, options.isForceParse))
        } else {
          // error可能在的值"timeout", "error", "notmodified"，"parsererror"
          reject({xhr, status, options})
        }

        // 结束回调
        if (typeof options.complete === 'function') {
          options.complete({xhr, status, options})
        }
      })

      const form = document.createElement('form')
      const node = document.createElement('input')
      // 请求类型
      form.method = options.method
      // 请求地址
      form.action = options.url
      // 在指定的iframe中执行form
      form.target = iframe.name

      // 连接 和 发送 - 第二步
      if (/^get$/i.test(options.method)) {
        options.url += '?' + options.params
        //设置表单提交时的内容类型
        Object.keys(options.headers).forEach((key) => {
          xhr.setRequestHeader(key, options.headers[key])
        })
      } else {
        for (let name in options.params) {
          node.name = name
          node.value = options.params[name].toString()
          form.appendChild(node.cloneNode())
        }
        //设置表单提交时的内容类型
        Object.keys(options.headers).forEach((key) => {
          xhr.setRequestHeader(key, options.headers[key])
        })
      }
      // 表单元素需要添加到主文档中.
      form.style.display = 'none'
      document.body.appendChild(form)
      form.submit()

      // 表单提交后,就可以删除这个表单,不影响下次的数据发送.
      document.body.removeChild(form)

      //超时处理
      if (options.timeout > 50) {
        let timer = setTimeout(function () {
          if (state !== 4) {
            isTimeout = true
            clearTimeout(timer)
          }
          reject({xhr, message: '超时'})
        }, options.timeout)
      }
    })
  }

  /**
   * @function 默认配置
   * @return {Object}
  */
  getDefaults () {
    /**
     * 默认配置
     * {
     *  url : <String>, 访问地址
     *  method : <String>, 访问类型，GET, POST, PUT, DELETE, HEAD
     *  data : <Object>, 数据
     *  body : <ArrayBuffer, ArrayBufferView(Uint8Array and friends), Blob/File, String, URLSearchParams, FormData>, 传输的数据
     *  dataType : <String>, 返回值类型
     *  headers : <Object>, 关联的Header对象
     *  cache : <String>, 缓存模式(default, reload, no-cache)
     *  timeout: <Int>, // 超时时间，默认-1永不过期
     *  async: {Boolean} // 是否异步步，默认true
     * }
    */
    return {
      url: '',
      method: 'POST',
      data: '',
      timeout: -1, // 默认-1永不过期
      async: true,
      dataType: 'object',
      isForceParse: false, // 是否强制转换
      withCredentials: true,
      // 请求头对象
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
        // 跨域携带cookie
        crossDomain: true,
        xhrFields: {
          withCredentials: true
        }
      }
    }
  }
}

export default new FormService
export {
  FormService
}